package de.saarland.uni.lego3d.server;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

import de.saarland.uni.lego3d.server.gui.MainGUI;

/**
 * Class representing the server.
 * It also contains the main method and the GUI implementation of Lego3D
 */
public class Server {

	/**
	 * Defines a reference to the Lego3D GUI
	 */
	public static MainGUI gui;

	/**
	 * Receiver thread that takes care of incoming kinect or android messages
	 */
	private ReceiverThread receiver;
	
	/**
	 * UDP port for the the server connection
	 */
	private final int PORT = 9876;
	
	/**
	 * The server socket
	 */
	private DatagramSocket serverSocket;
	
	/**
	 * Basic constructor for Server class that creates and starts a new Receiver Thread
	 */
	public Server () {
		try {
			this.serverSocket = new DatagramSocket(PORT);
			this.receiver = new ReceiverThread(serverSocket, new InteractionHandler(this));
			this.receiver.start();
		} catch (SocketException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Sends a callback message to the Adnroid device.
	 * @param IP - IP of the Android device
	 */
	public void sendConnectCallback(String IP) {
		try {
			byte[] sendData = new byte[1024];
			String msg = "CONNECTED";
			System.out.println("send message: " + msg + " to " + IP);
			sendData = msg.getBytes();
			DatagramPacket packet = new DatagramPacket(sendData, sendData.length, InetAddress.getByName(IP), PORT);
			sendPacket(packet);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * sends a datagram packet to the server
	 * @param p
	 */
	private synchronized void sendPacket(DatagramPacket p) {
		System.out.println("attemp to send message: " + p.toString());
		int tries = 0;
		while (tries < 3) {
			try {
				System.out.println("send: try*************************");
				serverSocket.send(p);
				System.out.println("send: successfull*************************");
				tries = 3;
			} catch (IOException e) {
				tries++;
			}
		}

	}
	
	/**
	 * Stops the seceiver thread.
	 */
	public void stopServer() {
		receiver.stop(true);
	}
}
